package model;

import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.List;

import model.objects.EntityObject;
import model.objects.ModelingObject;

import com.mxgraph.model.mxCell;
import com.mxgraph.view.mxGraph;

public class Modeling extends mxGraph {
	public static final NumberFormat numberFormat = NumberFormat.getInstance();
	protected Object edgeTemplate;
	public Modeling() {
		setAlternateEdgeStyle("edgeStyle=mxEdgeStyle.ElbowConnector;elbow=vertical");
		setCellsDisconnectable(false);
		setDropEnabled(false);
	}

	public void setEdgeTemplate(Object template) {
		edgeTemplate = template;
	}

	public Object createEdge(Object parent, String id, Object value,
			Object source, Object target, String style) {

		return super.createEdge(parent, id, value, source, target, style);
	}

	@Override
	public void setSelectionCell(Object cell) {
		if (((mxCell) cell).getStyle() == "straight")
			super.setSelectionCell(null);
		else if (((mxCell) cell).getStyle() != "associativeRelation")
			super.setSelectionCell(cell);
		else
			super.setSelectionCell(((mxCell)cell).getParent());
	}

	@Override
	public boolean isCellSelectable(Object cell) {
		return ((mxCell) cell).getStyle() != "straight";
	}

	@Override
	public Object[] removeCells(Object[] cells, boolean includeEdges) {

		if (cells == null)
			cells = getDeletableCells(getSelectionCells());

		removeReferencesFromParents(cells);

		List<Object> allRelatedCells = new ArrayList<Object>();
		addAllRelatedCells(cells, allRelatedCells);


		return super.removeCells(allRelatedCells.toArray(), includeEdges);
	}

	public void removeReferencesFromParents(Object[] cells) {
		for (int i = 0; i < cells.length; i++ ) {
			ModelingObject modelingObject = (ModelingObject)((mxCell)cells[i]).getValue();
			if (modelingObject != null)
				modelingObject.removeReferencesFromParents();
		}
	}

	public void addAllRelatedCells(Object[] cells, List<Object> allRelatedCells) {
		for (int i = 0; i < cells.length; i++ ) {
			mxCell cell = (mxCell) cells[i];
			if (cell.getValue() instanceof ModelingObject) {
				ModelingObject modelingObject = (ModelingObject)cell.getValue();

				if (!(cell.getValue() instanceof EntityObject) || 
						((cell.getValue() instanceof EntityObject) && ((EntityObject)cell.getValue()).getParentObjects().size() == 0)){
					addAllRelatedCells(modelingObject.getChildObjects().toArray(), allRelatedCells);
					allRelatedCells.add(cells[i]);
				}
			}
		}
	}
}